<template>
  <div>
    <h2>我是子级组件</h2>
    <h1>{{ msg }}</h1>
    <!-- <h1>count:{{ count }}</h1> -->
    <input type="text" :value="inputValue" @input="myInput" />
  </div>
</template>

<script lang="ts">
import { defineComponent, getCurrentInstance, ref } from 'vue'

export default defineComponent({
  name: 'Child',
  props: {
    msg: {
      type: String,
      default: ''
    },
    inputValue: {
      type: String,
      default: ''
    }
  },
  // setup细节问题
  // setup是在beforeCreate生命周期回调之前就执行了,而且就执行一次
  // 由此可以推断：setup在执行的时候，当前的组件还没有创建出来，也就意味着：组件实例对象this根本就不能用
  // this是undefined,说明,就不能通过this再去调用data/computed/methods/props中的相关内容
  // setup中一般返回一个对象,对象中的属性和方法都可以在html模板中使用
  // setup中的对象内部的属性和data函数中的return对象的属性都可以在html模板中使用
  // setup中的对象中的属性和data函数中的对象中的属性会合并为组件对象的属性
  // setup中的对象中的方法和methods对象中的方法会合并为组件对象的方法
  // 尽量不要混合使用
  // setup不能是一个async函数:因为返回值不再是return的对象s,而是promise,模板看不到return对象中的数据属性

  // 数据初始化的生命周期回调
  beforeCreate() {
    console.log('beforeCreate执行了')
  },
  setup(props, context) {
    // props参数，是一个对象,里面有父级组件向子级组件传递的数据,并且是在子级组件中使用props接收到的所有的属性
    // 包含props配置声明且传入了的所有属性的对象
    console.log(props, context)
    // context参数,是一个对象，里面有attrs对象(获取当前组件标签上的所有的属性的对象，但是该属性是在props中没有声明接收的所有的尚需使用的对象)emit(分发事件)slots对象(插槽)
    // 包含没有在props配置中声明的属性的对象，相当于this.$attrs
    console.log(context.attrs)
    console.log(context.emit)
    console.log(context.slots)

    // const { proxy: _this } = getCurrentInstance()
    // console.log('setup执行了', this, _this)
    console.log('setup执行了', this)
    const message = ref('哈哈')
    const myInput = (e: any) => {
      console.log(e.target.value)
      context.emit('update:inputValue', e.target.value)
    }
    const btn1Click = () => {}
    // setup中一般返回一个对象，对象中的属性和方法都可以在html模板中直接使用
    return {
      message,
      btn1Click,
      myInput
    }
  }
  // data() {
  //   return {
  //     count: 10
  //   }
  // },
  // mounted() {
  //   console.log(this)
  // },
  // methods: {
  //   btnClick() {}
  // }
})
</script>

<style lang="scss" scoped>
</style>